package command

import "fmt"

// Command 命令接口，声明执行的操作
type Command interface {
	// Execute 执行命令对应的操作
	Execute()
}

// 多个命令Command，一个Invoker

// ConcreteCommandA 具体的命令实现对象
type ConcreteCommandA struct {
	receiver *Receiver // 持有响应的接受者对象
	state    string    // 示意，命令对象可以有自己的状态
}

// NewCommandA 构造方法，传入相应的接受者对象
func NewCommandA(receiver *Receiver) *ConcreteCommandA {
	return &ConcreteCommandA{
		receiver: receiver,
	}
}

func (c *ConcreteCommandA) Execute() {
	// 通常会转调接收者对象的相应方法，让接收者来真正执行功能
	c.receiver.Action1()
}

// ConcreteCommandB 具体的命令实现对象
type ConcreteCommandB struct {
	receiver *Receiver // 持有响应的接受者对象
	state    string    // 示意，命令对象可以有自己的状态
}

// NewCommandB 构造方法，传入相应的接受者对象
func NewCommandB(receiver *Receiver) *ConcreteCommandB {
	return &ConcreteCommandB{
		receiver: receiver,
	}
}

func (c *ConcreteCommandB) Execute() {
	// 通常会转调接收者对象的相应方法，让接收者来真正执行功能
	c.receiver.Action2()
}

// Receiver 接收者对象
type Receiver struct {
}

// Action1 示意方法，真正执行命令相应的操作
func (r *Receiver) Action1() {
	// 真正执行命令操作的功能代码
	fmt.Println("receiver action one")
}

// Action2 示意方法，真正执行命令相应的操作
func (r *Receiver) Action2() {
	// 真正执行命令操作的功能代码
	fmt.Println("receiver action two")
}

// Invoker 调用者，可以持有多个命令
type Invoker struct {
	command1 Command // 持有命令对象
	command2 Command // 持有命令对象
}

// SetCommand1 设置调用者持有的命令对象
func (i *Invoker) SetCommand1(command Command) {
	i.command1 = command
}

// SetCommand2 设置调用者持有的命令对象
func (i *Invoker) SetCommand2(command Command) {
	i.command2 = command
}

// RunCommand1 示意方法，要求命令执行请求
func (i *Invoker) RunCommand1() {
	// 调用命令对象的执行方法
	i.command1.Execute()
}

// RunCommand2 示意方法，要求命令执行请求
func (i *Invoker) RunCommand2() {
	// 调用命令对象的执行方法
	i.command2.Execute()
}
